package top.whysu.edevice.service.ezviz.impl;

import com.alibaba.fastjson.JSON;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import top.whysu.edevice.constant.CodeConstant;
import top.whysu.edevice.dao.manage.ManageDeviceDao;
import top.whysu.edevice.dao.manage.ManageSecretKeyDao;
import top.whysu.edevice.dao.relative.RelativeVoucherAccountDao;
import top.whysu.edevice.dao.system.AccountDao;
import top.whysu.edevice.dto.device.DeviceAddModifyDTO;
import top.whysu.edevice.dto.ezviz.child.*;
import top.whysu.edevice.dto.ezviz.device.EzvizDeviceAddDTO;
import top.whysu.edevice.dto.ezviz.device.EzvizDeviceDeleteDTO;
import top.whysu.edevice.dto.ezviz.token.TokenDTO;
import top.whysu.edevice.dto.ezviz.token.TokenWithAccountDTO;
import top.whysu.edevice.exception.BusinessException;
import top.whysu.edevice.po.manage.ManageDevicePO;
import top.whysu.edevice.po.system.AccountPO;
import top.whysu.edevice.po.system.RolePO;
import top.whysu.edevice.service.ezviz.EzvizHttpService;
import top.whysu.edevice.service.ezviz.EzvizService;
import top.whysu.edevice.service.ezviz.EzvizTokenService;
import top.whysu.edevice.service.manage.ManageDeviceService;
import top.whysu.edevice.service.system.RoleService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("EzvizChildAccountServiceImpl")
public class EzvizServiceImpl implements EzvizService {
    private static final Logger LOGGER = LoggerFactory.getLogger(EzvizServiceImpl.class);

    @Resource
    private EzvizHttpService ezvizHttpService;
    @Resource
    private ManageSecretKeyDao manageSecretKeyDao;
    @Resource
    private AccountDao accountDao;
    @Resource
    private EzvizTokenService ezvizTokenService;
    @Resource
    private RelativeVoucherAccountDao relativeVoucherAccountDao;
    @Resource
    private ManageDeviceDao manageDeviceDao;
    @Resource
    private ManageDeviceService manageDeviceService;
    @Resource
    private RoleService roleService;

    @Override
    public void createChildAccount(BigDecimal accountId, BigDecimal voucherId) {
        // 查询账号
        AccountPO accountPO = accountDao.selectById(accountId);
        if (accountPO != null) {
            // 获取accessToken等信息
            TokenWithAccountDTO tokenDTO = ezvizTokenService.getToken(accountId, voucherId);
            // 新增子账号
            ChildCreateRequestDTO childCreateRequestDTO = new ChildCreateRequestDTO();
            childCreateRequestDTO.setAccessToken(tokenDTO.getAccessToken());
            childCreateRequestDTO.setAccountName(tokenDTO.getUsername());
            childCreateRequestDTO.setPassword(ezvizTokenService.ezvizPassword("123456", tokenDTO.getAppKey()));
            ChildCreateResponseDTO responseDTO = ezvizHttpService.createChildAccount(childCreateRequestDTO);
            // 萤石accountId
            accountPO.setEzvizAccountId(responseDTO.getAccountId());
            accountPO.setUpdateTime(new Date());
            accountDao.update(accountPO);
        }
    }

    @Override
    public void deleteChildAccount(BigDecimal accountId, BigDecimal voucherId) {
        AccountPO accountPO = accountDao.selectById(accountId);
        if (accountPO != null && accountPO.getEzvizAccountId() != null) {
            // 获取accessToken等信息
            TokenWithAccountDTO tokenDTO = ezvizTokenService.getToken(accountId, voucherId);
            // 删除萤石上的子账号
            ChildDeleteRequestDTO requestDTO = new ChildDeleteRequestDTO();
            requestDTO.setAccessToken(tokenDTO.getAccessToken());
            requestDTO.setAccountId(accountPO.getEzvizAccountId());
            ezvizHttpService.deleteChildAccount(requestDTO);
        }
    }

    @Override
    public void createDevice(BigDecimal voucherId, DeviceAddModifyDTO deviceAddModifyDTO) {
        // 获取token
        TokenDTO tokenDTO = ezvizTokenService.getTokenByVoucherId(voucherId);
        // 封装参数
        EzvizDeviceAddDTO ezvizDeviceAddDTO = new EzvizDeviceAddDTO();
        ezvizDeviceAddDTO.setAccessToken(tokenDTO.getAccessToken());
        // 设备序列号
        ezvizDeviceAddDTO.setDeviceSerial(deviceAddModifyDTO.getDeviceSerial());
        // 设备验证码
        ezvizDeviceAddDTO.setValidateCode(deviceAddModifyDTO.getDeviceCode());
        ezvizHttpService.addDevice(ezvizDeviceAddDTO);
    }

    @Override
    public void deleteDevice(ManageDevicePO manageDevicePO) {
        // 获取token
        TokenDTO tokenDTO = ezvizTokenService.getTokenByVoucherId(manageDevicePO.getVoucherId());
        // 封装参数
        EzvizDeviceDeleteDTO deviceDeleteDTO = new EzvizDeviceDeleteDTO();
        deviceDeleteDTO.setAccessToken(tokenDTO.getAccessToken());
        deviceDeleteDTO.setDeviceSerial(manageDevicePO.getDeviceSerial());
        ezvizHttpService.deleteDevice(deviceDeleteDTO);
    }

    @Override
    public void setPolicyAfterAssignAccount(BigDecimal accountId, BigDecimal voucherId) {
        if (accountId == null || voucherId == null) {
            throw new BusinessException(CodeConstant.Http.EXECUTE_FAIL, "账号id和凭证组id不能为空！");
        }
        // 查询凭证组下的设备
        List<ManageDevicePO> deviceList = manageDeviceService.getDeviceListByVoucherId(voucherId);
        if (CollectionUtils.isEmpty(deviceList)) {
            LOGGER.info("当前凭证组下没有设备，不进行授权，voucherId: {}, accountId: {}", voucherId, accountId);
            return;
        }
        // 查询当前账号的角色
        List<RolePO> roleInfos = roleService.selectRolesByUserId(accountId);
        if (CollectionUtils.isEmpty(roleInfos)) {
            LOGGER.info("当前账号未分配角色权限，不进行授权，voucherId: {}, accountId: {}", voucherId, accountId);
            return;
        }
        // 获取accessToken
        TokenWithAccountDTO tokenDTO = ezvizTokenService.getToken(accountId, voucherId);
        deviceList.forEach(manageDevicePO -> {
            // 授权
            ChildSetPolicyDTO childSetPolicyDTO = new ChildSetPolicyDTO();
            childSetPolicyDTO.setAccessToken(tokenDTO.getAccessToken());
            childSetPolicyDTO.setAccountId(tokenDTO.getEzvizAccountId());
            childSetPolicyDTO.setPolicy(JSON.toJSONString(ezvizTokenService.getPolicy(deviceList, roleInfos.get(0).getRoleSign())));
            ezvizHttpService.childSetPolicy(childSetPolicyDTO);
        });
    }

    @Override
    public void addDeviceToAccountByVoucher(BigDecimal voucherId, BigDecimal deviceId) {
        if (voucherId == null || deviceId == null) {
            throw new BusinessException(CodeConstant.Http.EXECUTE_FAIL, "凭证组id和设备id不能为空！");
        }
        // 查询设备
        ManageDevicePO manageDevicePO = manageDeviceDao.queryById(deviceId);
        if (manageDevicePO == null) {
            LOGGER.error("添家设备到凭证组下的所有账号, 设备不存在， voucherId: {}, deviceId: {}", voucherId, deviceId);
            return;
        }
        // 查询该凭证组下的所有账号信息
        List<TokenWithAccountDTO> tokenAccountList = ezvizTokenService.getTokenAccountList(voucherId);
        if (CollectionUtils.isNotEmpty(tokenAccountList)) {
            // 需要将这台设备封装成集合供方法调用
            List<ManageDevicePO> manageDevicePOList = new ArrayList<>();
            manageDevicePOList.add(manageDevicePO);
            // 将当前设备添加到这些子账号里面
           for (TokenWithAccountDTO it : tokenAccountList) {
                DeviceAddToChildDTO addToChildDTO = new DeviceAddToChildDTO();
                addToChildDTO.setAccessToken(it.getAccessToken());
                addToChildDTO.setAccountId(it.getEzvizAccountId());
                // 查询当前账号的角色
                List<RolePO> roleInfos = roleService.selectRolesByUserId(it.getAccountId());
                if (CollectionUtils.isEmpty(roleInfos)) {
                    LOGGER.info("添加设备分配子账号权限，当前账号未分配角色权限，不进行授权, 继续下一个，voucherId: {}, accountId: {}", voucherId, it.getAccountId());
                    continue;
                }
                addToChildDTO.setStatement(JSON.toJSONString(ezvizTokenService.getStatement(manageDevicePOList, roleInfos.get(0).getRoleSign())));
                ezvizHttpService.deviceAddToAccount(addToChildDTO);
            }
        }

    }

}
